package com.zyf.chapter02.creation.factory.DI;

import com.zyf.chapter02.creation.factory.DI.util.NoSuchBeanDefinitionException;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * XML DI 容器
 * <p>组装类并提供执行入口，组装{@link BeansFactory}和{@link BeanConfigParser}
 *
 * <p>串联执行流程：从 classpath 中加载 XML 格式的配置文件，通过 Bean ConfigParser 解析为统一的
 * {@link BeanDefinition} 格式，然后，{@link BeansFactory}根据{@link BeanDefinition}来创建对象
 * @author yifeng
 */
public class ClassPathXmlApplicationContext implements ApplicationContext {
    private BeansFactory beansFactory;
    private BeanConfigParser beanConfigParser;

    public ClassPathXmlApplicationContext(String configLocation) {
        this.beansFactory = new BeansFactory();
        this.beanConfigParser = new XmlBeanConfigParser();
        loadBeanDefinitions(configLocation);
    }

    private void loadBeanDefinitions(String configLocation) {
        try(InputStream in = this.getClass().getResourceAsStream("/" + configLocation)) {
            if (in == null) {
                throw new RuntimeException("Can not find config file: " + configLocation);
            }
            List<BeanDefinition> beanDefinitions = beanConfigParser.parse(in);
            beansFactory.addBeanDefinitions(beanDefinitions);
        } catch (IOException | NoSuchBeanDefinitionException e) {
            // log error
        }
    }

    @Override
    public Object getBean(String beanId) throws NoSuchBeanDefinitionException {
        return beansFactory.getBean(beanId);
    }
}
